package com.example.rxactivity;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

import com.example.rxactivity.model.Person;
import com.example.rxactivity.model.Plan;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.btn1)
    Button btn1;
    @BindView(R.id.btn2)
    Button btn2;
    @BindView(R.id.btn3)
    Button btn3;
    @BindView(R.id.btn4)
    Button btn4;
    @BindView(R.id.btn5)
    Button btn5;
    @BindView(R.id.btn6)
    Button btn6;
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);


    }


    @OnClick({R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4, R.id.btn5, R.id.btn6})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn1:
                toGoActivity(this, CreateActivity.class);
                break;
            case R.id.btn2:
                toGoActivity(this, FromActivity.class);
                break;
            case R.id.btn3:
                break;
            case R.id.btn4:
                break;
            case R.id.btn5:
                break;
            case R.id.btn6:
                break;
        }
    }

    private static void toGoActivity(Context context, Class<?> cla) {
        context.startActivity(new Intent(context, cla));
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (compositeDisposable != null) {
            compositeDisposable.clear();
            compositeDisposable.dispose();
            compositeDisposable = null;
        }
    }


    public void btn1(View view) {
        Disposable disposable = Flowable.interval(5, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .take(2)
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.d("main", "accept: " + aLong);
                    }
                });

        compositeDisposable.add(disposable);
    }

    public void btn2(View view) {

        Disposable disposable = Observable.interval(5, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .take(2)
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(new Function<Long, ObservableSource<Long>>() {
                    @Override
                    public ObservableSource<Long> apply(Long aLong) throws Exception {
                        return Observable.just(aLong);
                    }
                }).subscribe(new Consumer<Long>() {
                                 @Override
                                 public void accept(Long aLong) throws Exception {
                                     Log.d("main", "accept: " + aLong);
                                 }
                             }, new Consumer<Throwable>() {
                                 @Override
                                 public void accept(Throwable throwable) throws Exception {

                                 }
                             }
                );
        compositeDisposable.add(disposable);


    }

    public void Create(View view) {

        Disposable disposable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("这");
                emitter.onNext("是");
                emitter.onNext("Create");
                emitter.onNext("练");
                emitter.onNext("习");
            }
        })
                .observeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                               @Override
                               public void accept(String s) throws Exception {
                                   Log.d("main", "accept: create-->" + s);
                               }
                           }, new Consumer<Throwable>() {
                               @Override
                               public void accept(Throwable throwable) throws Exception {

                               }
                           }
                );
        compositeDisposable.add(disposable);

    }

    public void Just(View view) {
        Disposable disposable = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                               @Override
                               public void accept(Integer integer) throws Exception {
                                   Log.d("main", "accept: just -- >" + integer + "");
                               }
                           }, new Consumer<Throwable>() {
                               @Override
                               public void accept(Throwable throwable) throws Exception {

                               }
                           }
                );
        compositeDisposable.add(disposable);
    }


    /**
     * 因为 defer() 只有观察者订阅的时候才会创建新的被观察者，所以每订阅一次就会打印一次，并且都是打印 i 最新的值
     *
     * @param view k
     * 最终打印结果为 200 300 400 因为传入100的时候 观察者还没订阅
     */
    // i 要定义为成员变量
    Integer i = 100;

    public void defer(View view) {

        Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<? extends Integer>>() {
            @Override
            public ObservableSource<? extends Integer> call() throws Exception {
                return Observable.just(i);
            }
        });
        i = 200;
        Observer observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Integer o) {
                Log.d("main", "onNext:  defer-->" + o);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        };
        observable.subscribe(observer);
        i = 300;
        observable.subscribe(observer);
        i = 400;
        observable.subscribe(observer);


    }


    public void intervalRange(View view) {
        //轮讯 计时
//        Disposable disposable = Observable.intervalRange(1, 60, 1, 1, TimeUnit.SECONDS)
//                .subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .map(new Function<Long, Long>() {
//                    @Override
//                    public Long apply(Long aLong) throws Exception {
//                        long l = 60 - aLong;
//                        Log.e("main", "apply:  60 - " + aLong + "=" + l);
//                        return l;
//                    }
//                })
//                .subscribe(new Consumer<Long>() {
//                               @Override
//                               public void accept(Long aLong) throws Exception {
//                                   Log.d("main", "accept: 剩余秒数 " + aLong + "'s");
//                               }
//                           }, new Consumer<Throwable>() {
//                               @Override
//                               public void accept(Throwable throwable) throws Exception {
//
//                               }
//                           }
//                );
//        compositeDisposable.add(disposable);

        // 无限循环
        Disposable disposable = Observable.interval(1, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .take(10)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Long>() {
                               @Override
                               public void accept(Long aLong) throws Exception {
                                   Log.d("main", "accept: 剩余秒数 " + aLong + "'s");
                               }
                           }, new Consumer<Throwable>() {
                               @Override
                               public void accept(Throwable throwable) throws Exception {
                                   Log.e("main", "accept: " + throwable.toString());
                               }
                           }, new Action() {
                               @Override
                               public void run() throws Exception {
                                   Log.w("main", "run: ");
                               }
                           }
                );
        compositeDisposable.add(disposable);

    }


    /**
     * @param view k
     * @fromIterable 把集合注逐一发送出去
     * @fromMap 返回一个新的集合
     * @concatMap 和fromMap一样  但是fromMap是无序的 concatMap是有序的
     */
    public void FromMap(View view) {
        ArrayList<Person> person = new ArrayList<>();
        ArrayList<Plan> plan = new ArrayList<>();
        ArrayList<String> list = new ArrayList<>();
        list.add("一");
        list.add("二");
        list.add("三");
        list.add("四");
        list.add("五");
        list.add("结束一轮");
        plan.add(new Plan("1", "第一条数据", list));
        plan.add(new Plan("2", "第二条数据", list));
        plan.add(new Plan("3", "第三条数据", list));
        plan.add(new Plan("4", "第四条数据", list));
        plan.add(new Plan("5", "第五条数据", list));
        plan.add(new Plan("6", "第六条数据", list));
        person.add(new Person("糖豆豆", plan));
        person.add(new Person("李豆豆", plan));
        person.add(new Person("王豆豆", plan));
        person.add(new Person("样豆豆", plan));
        person.add(new Person("张豆豆", plan));
        Disposable disposable = Observable.fromIterable(person)
                .flatMap(new Function<Person, ObservableSource<Plan>>() {
                    @Override
                    public ObservableSource<Plan> apply(Person person) throws Exception {
                        return Observable.fromIterable(person.getPlanList());
                    }
                })
                .concatMap(new Function<Plan, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(Plan plan) throws Exception {
                        return Observable.fromIterable(plan.getActionList()).delay(10, TimeUnit.MILLISECONDS);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                               @Override
                               public void accept(String s) throws Exception {
                                   Log.d("main", "accept:     获取到的数据是 --> " + s);
                               }
                           }, new Consumer<Throwable>() {
                               @Override
                               public void accept(Throwable throwable) throws Exception {

                               }
                           }
                );
        compositeDisposable.add(disposable);

    }


    /**
     * 当 skipUntil() 中的 Observable 发送事件了，原来的 Observable 才会发送事件给观察者。
     *
     * @param view k
     */
    public void skipUntil(View view) {

        Disposable disposable = Observable.intervalRange(1, 5, 1, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .skipUntil(Observable.intervalRange(6, 5, 1, 1, TimeUnit.SECONDS))
                .subscribe(new Consumer<Long>() {
                               @Override
                               public void accept(Long aLong) throws Exception {
                                   Log.d("main", "accept:   skipUntil -->  " + aLong);
                               }
                           }, new Consumer<Throwable>() {
                               @Override
                               public void accept(Throwable throwable) throws Exception {

                               }
                           }
                );

        compositeDisposable.add(disposable);
    }


//    BiFunction

}
